package com.skyd.core.android.game;

import java.util.ArrayList;

/**
 * 表示运动，如坐标移动、尺寸缩放、不透明度变化
 * 
 * @author SkyD
 * 
 */
public abstract class GameMotion {

	/**
	 * 构造函数
	 */
	public GameMotion() {

	}

	/**
	 * 构造函数
	 * 
	 * @param duration
	 *            持续时间
	 */
	public GameMotion(int duration) {
		setDuration(duration);
	}

	/**
	 * 初始值为0。 功能注释：持续时间，如为-1则不限制时间
	 */
	private int _Duration = 0;

	/**
	 * 获取Duration。 功能注释：持续时间，如为-1则不限制时间
	 * 
	 * @return 当前的int类型的值
	 */
	public int getDuration() {
		return _Duration;
	}

	/**
	 * 设置Duration。 功能注释：持续时间，如为-1则不限制时间
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	public void setDuration(int value) {
		_Duration = value;
	}

	/**
	 * 设置Duration为其默认值(0)。 功能注释：持续时间，如为-1则不限制时间
	 */
	public void setDurationToDefault() {
		setDuration(0);
	}

	/**
	 * 初始值为0。 功能注释：游戏帧计数，用于控制动画帧步进
	 */
	private int _FrameCounting = 0;

	/**
	 * 获取FrameCounting。 功能注释：游戏帧计数，用于控制帧步进
	 * 
	 * @return 当前的int类型的值
	 */
	public int getFrameCounting() {
		return _FrameCounting;
	}

	/**
	 * 设置FrameCounting。 功能注释：游戏帧计数，用于控制帧步进
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	protected void setFrameCounting(int value) {
		_FrameCounting = value;
	}

	/**
	 * 设置FrameCounting为其默认值(0)。 功能注释：游戏帧计数，用于控制帧步进
	 */
	protected void setFrameCountingToDefault() {
		setFrameCounting(0);
	}

	/**
	 * 初始值为0。 功能注释：循环播放次数计数
	 */
	private int _LoopCounting = 0;

	/**
	 * 获取LoopCounting。 功能注释：循环播放次数计数
	 * 
	 * @return 当前的int类型的值
	 */
	public int getLoopCounting() {
		return _LoopCounting;
	}

	/**
	 * 设置LoopCounting。 功能注释：循环播放次数计数
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	protected void setLoopCounting(int value) {
		_LoopCounting = value;
	}

	/**
	 * 设置LoopCounting为其默认值(0)。 功能注释：循环播放次数计数
	 */
	protected void setLoopCountingToDefault() {
		setLoopCounting(0);
	}

	/**
	 * 初始值为0。 功能注释：指示循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 */
	private int _LoopTime = 0;

	/**
	 * 获取LoopTime。 功能注释：指示循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 * 
	 * @return 当前的int类型的值
	 */
	public int getLoopTime() {
		return _LoopTime;
	}

	/**
	 * 设置LoopTime。 功能注释：指示循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	public void setLoopTime(int value) {
		_LoopTime = value;
	}

	/**
	 * 设置LoopTime为其默认值(0)。 功能注释：指示循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 */
	public void setLoopTimeToDefault() {
		setLoopTime(0);
	}

	/**
	 * 返回运动是否完成，如果完成将会启动下一次循环或终止此运动
	 * 
	 * @param obj
	 *            更新的目标对象
	 * 
	 * @return 运动是否完成
	 */
	protected boolean getIsComplete(GameObject obj) {
		return getFrameCounting() >= getDuration();
	}

	/**
	 * 更新，每次执行此函数既表示游戏前进了1帧，如果处于未运行状态则忽略此操作
	 * 
	 * @param obj
	 *            更新的目标对象
	 */
	public final void update(GameObject obj) {
		if (!getIsRunning()
				|| (getBeforeTransformation() != null && !getIsBeforeTransformationCompleted()))
			return;
		updateSelf(obj);
		updateTarget(obj);
		setFrameCounting(getFrameCounting() + 1);
		if (getIsComplete(obj)) {
			onComplete(obj);
			setLoopCounting(getLoopCounting() + 1);
			if (getLoopTime() >= 0) {
				if (getLoopCounting() > getLoopTime()) {
					stop();
				} else {
					setFrameCounting(0);
					restart(obj);
				}
			}
		}
	}

	/**
	 * 更新自身
	 * 
	 * @param obj
	 *            更新的目标对象
	 */
	protected abstract void updateSelf(GameObject obj);

	/**
	 * 更新目标，在更新自身后被调用
	 * 
	 * @param obj
	 *            更新的目标对象
	 */
	protected abstract void updateTarget(GameObject obj);

	/**
	 * 重新播放，重新开始循环时执行此操作，此时帧计数是归零的，播放状态仍为true
	 * 
	 * @param obj
	 *            更新的目标对象
	 */
	protected abstract void restart(GameObject obj);

	/**
	 * 开始播放动画，首次播放或从停止状态中恢复播放时执行此函数
	 */
	public void start() {
		setIsRunning(true);
	}

	/**
	 * 动画停在当前帧，暂停播放
	 */
	public void stop() {
		setIsRunning(false);
	}

	/**
	 * 初始值为false。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 */
	private boolean _IsRunning = false;

	/**
	 * 获取IsRunning。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 * 
	 * @return 当前的boolean类型的值
	 */
	public boolean getIsRunning() {
		return _IsRunning;
	}

	/**
	 * 设置IsRunning。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 * 
	 * @param value
	 *            要设置的boolean类型值
	 */
	protected void setIsRunning(boolean value) {
		if (_IsRunning != value)
			onIsRunningChanged(value);
		_IsRunning = value;
	}

	/**
	 * 设置IsRunning为其默认值(false)。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 */
	protected void setIsRunningToDefault() {
		setIsRunning(false);
	}

	/**
	 * 当运动完成（达到预定目标）时触发
	 */
	public interface OnCompleteListener {
		/**
		 * 触发Complete事件时执行的方法。事件功能注释：当运动完成（达到预定目标）时触发
		 * 
		 * @param sender
		 *            触发Complete事件的对象
		 */
		public abstract void OnCompleteEvent(Object sender, GameObject targetObj);
	}

	/**
	 * Complete事件监听器列表。当运动完成（达到预定目标）时触发
	 */
	private ArrayList<OnCompleteListener> _CompleteListenerList = null;

	/**
	 * 增加一个Complete事件的监听器，返回是否成功增加。事件功能注释：当运动完成（达到预定目标）时触发
	 * 
	 * @param listener
	 *            Complete事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnCompleteListener(OnCompleteListener listener) {
		if (_CompleteListenerList == null)
			_CompleteListenerList = new ArrayList<OnCompleteListener>();
		else if (_CompleteListenerList.contains(listener))
			return false;
		_CompleteListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个Complete事件的监听器，返回是否成移除。事件功能注释：当运动完成（达到预定目标）时触发
	 * 
	 * @param listener
	 *            Complete事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnCompleteListener(OnCompleteListener listener) {
		if (_CompleteListenerList == null
				|| !_CompleteListenerList.contains(listener))
			return false;
		_CompleteListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有Complete事件的监听器。事件功能注释：当运动完成（达到预定目标）时触发
	 */
	public void clearOnCompleteListeners() {
		if (_CompleteListenerList != null)
			_CompleteListenerList.clear();
	}

	/**
	 * 当运动完成（达到预定目标）时触发
	 */
	protected void onComplete(GameObject targetObj) {
		if (_CompleteListenerList != null)
			for (OnCompleteListener listener : _CompleteListenerList) {
				listener.OnCompleteEvent(this, targetObj);
			}
	}

	/**
	 * 当运行状态变更后触发
	 */
	public interface OnIsRunningChangedListener {
		/**
		 * 触发IsRunningChanged事件时执行的方法。事件功能注释：当运行状态变更后触发
		 * 
		 * @param sender
		 *            触发IsRunningChanged事件的对象
		 */
		public abstract void OnIsRunningChangedEvent(Object sender,
				boolean newValue);
	}

	/**
	 * IsRunningChanged事件监听器列表。当运行状态变更后触发
	 */
	private ArrayList<OnIsRunningChangedListener> _IsRunningChangedListenerList = null;

	/**
	 * 增加一个IsRunningChanged事件的监听器，返回是否成功增加。事件功能注释：当运行状态变更后触发
	 * 
	 * @param listener
	 *            IsRunningChanged事件监听器对象
	 * @return 是否成功增加。如果该监听器对象已存在，则返回false。
	 */
	public boolean addOnIsRunningChangedListener(
			OnIsRunningChangedListener listener) {
		if (_IsRunningChangedListenerList == null)
			_IsRunningChangedListenerList = new ArrayList<OnIsRunningChangedListener>();
		else if (_IsRunningChangedListenerList.contains(listener))
			return false;
		_IsRunningChangedListenerList.add(listener);
		return true;
	}

	/**
	 * 移除一个IsRunningChanged事件的监听器，返回是否成移除。事件功能注释：当运行状态变更后触发
	 * 
	 * @param listener
	 *            IsRunningChanged事件监听器对象
	 * @return 是否成功移除。如果该监听器对象不存在，则返回false。
	 */
	public boolean removeOnIsRunningChangedListener(
			OnIsRunningChangedListener listener) {
		if (_IsRunningChangedListenerList == null
				|| !_IsRunningChangedListenerList.contains(listener))
			return false;
		_IsRunningChangedListenerList.remove(listener);
		return true;
	}

	/**
	 * 清空所有IsRunningChanged事件的监听器。事件功能注释：当运行状态变更后触发
	 */
	public void clearOnIsRunningChangedListeners() {
		if (_IsRunningChangedListenerList != null)
			_IsRunningChangedListenerList.clear();
	}

	/**
	 * 当运行状态变更后触发
	 */
	protected void onIsRunningChanged(boolean newValue) {
		if (_IsRunningChangedListenerList != null)
			for (OnIsRunningChangedListener listener : _IsRunningChangedListenerList) {
				listener.OnIsRunningChangedEvent(this, newValue);
			}
	}

	/**
	 * 初始值为null。 功能注释：之前的运动对象，只有当该对象停止时才正式运行
	 */
	private GameMotion _BeforeTransformation = null;

	/**
	 * 获取BeforeTransformation。 功能注释：之前的运动对象，只有当该对象停止时才正式运行
	 * 
	 * @return 当前的GameTransformation类型的值
	 */
	public GameMotion getBeforeTransformation() {
		return _BeforeTransformation;
	}

	/**
	 * 设置BeforeTransformation。 功能注释：之前的运动对象，只有当该对象停止时才正式运行
	 * 
	 * @param value
	 *            要设置的GameTransformation类型值
	 */
	public void setBeforeTransformation(GameMotion value) {
		if (value != null) {
			value
					.addOnIsRunningChangedListener(BeforeTransformationRunningChangeListener);
		}
		if (_BeforeTransformation != null) {
			_BeforeTransformation
					.removeOnIsRunningChangedListener(BeforeTransformationRunningChangeListener);
		}
		_BeforeTransformation = value;
	}

	OnIsRunningChangedListener BeforeTransformationRunningChangeListener = new OnIsRunningChangedListener() {

		@Override
		public void OnIsRunningChangedEvent(Object sender, boolean newValue) {
			if (!newValue) {
				setIsBeforeTransformationCompleted(true);
			}
		}
	};

	/**
	 * 设置BeforeTransformation为其默认值(null)。 功能注释：之前的运动对象，只有当该对象停止时才正式运行
	 */
	public void setBeforeTransformationToDefault() {
		setBeforeTransformation(null);
	}

	/**
	 * 初始值为false。 功能注释：指示排在前面的运动是否已完成
	 */
	private boolean _IsBeforeTransformationCompleted = false;

	/**
	 * 获取IsBeforeTransformationCompleted。 功能注释：指示排在前面的运动是否已完成
	 * 
	 * @return 当前的boolean类型的值
	 */
	public boolean getIsBeforeTransformationCompleted() {
		return _IsBeforeTransformationCompleted;
	}

	/**
	 * 设置IsBeforeTransformationCompleted。 功能注释：指示排在前面的运动是否已完成
	 * 
	 * @param value
	 *            要设置的boolean类型值
	 */
	protected void setIsBeforeTransformationCompleted(boolean value) {
		_IsBeforeTransformationCompleted = value;
	}

	/**
	 * 设置IsBeforeTransformationCompleted为其默认值(false)。 功能注释：指示排在前面的运动是否已完成
	 */
	protected void setIsBeforeTransformationCompletedToDefault() {
		setIsBeforeTransformationCompleted(false);
	}
}
